Skip to content

Conversation

@zharinov
Copy link
Member

@zharinov zharinov commented Jan 3, 2026

Summary

  • Fix duplicate matches when sequences contain alternations (e.g., {[A B] @x}*)
  • Change Call/Return from position-based to depth-based cursor restoration
  • Preserve sibling advances from continue_search while restoring tree level when callee descended

Problem

When {[A B] @x}* iterates:

  1. First iteration: Alt matches at lexical_declaration via continue_search
  2. Return restores cursor to { (saved at Call time)
  3. Repeat's Nav::Next from { goes to lexical_declaration again
  4. Alt matches the same node → duplicate!

Solution

Instead of saving/restoring exact cursor position, save/restore tree depth:

  • At Call: save cursor.depth()
  • At Return: go up to saved depth (if descended) or stay put (if same level)

This preserves sibling advances while correctly restoring level after descending into children.

Test plan

  • All 751 existing tests pass
  • Bug reproduction now returns 2 matches instead of 3:
    cargo run -p plotnik-cli -- exec -q '
    Alt = [(lexical_declaration) (return_statement)]
    Q = (program (function_declaration body: (statement_block {(Alt) @a}* @all)))
    ' -s 'function f() { let x = 1; return x; }' -l javascript --entry Q
    

When a callee advances via continue_search at the same tree level,
the cursor should stay at the matched position. Previously, Return
always restored to the exact position saved at Call time, causing
duplicate matches when sequences contained alternations.

Changed from saving/restoring cursor position (descendant_index) to
saving/restoring cursor depth. On Return, we go up to the saved
depth level, which preserves sibling advances while still restoring
level when the callee descended into children.
@zharinov zharinov enabled auto-merge (squash) January 3, 2026 20:07
@zharinov zharinov merged commit bce584d into master Jan 3, 2026
4 checks passed
@zharinov zharinov deleted the fix/depth-cursor-restore branch January 3, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants